<?php
declare(strict_types=1);

namespace App\Utils\Other\Safepay;

use App\Exception\InternalException;
use App\Utils\Http\Request;
use Hyperf\Collection\Arr;
use Hyperf\Context\Context;
use function Hyperf\Config\config;
use function Hyperf\Support\make;

Class App {

    public function __construct()
    {
        $this->setConfig(config('cloud.safepay'));
    }

    /**
     * 设置配置
     * @param array|null $config
     * @return $this
     */
    public function setConfig(?array $config):static
    {
        if (!$config) {
            Context::set(static::class.'_config', []);
            return $this;
        }

        $configData = $this->getConfig();
        $config = array_merge($configData, $config);
        Context::set(static::class.'_config', $config);
        return $this;
    }

    /**
     * 获取配置
     * @param string|null $key
     * @param mixed $default
     * @return mixed
     */
    public function getConfig(?string $key=null, mixed $default=[]):mixed
    {
        $config = Context::get(static::class.'_config', []);
        return $key?Arr::get($config, $key, $default):$config;
    }

    /**
     * 设置路径
     * @param string $path
     * @return $this
     */
    protected function setPath(string $path):static
    {
        $this->setConfig(['path'=>$path]);
        return $this;
    }

    /**
     * 获取当前路径
     * @return string
     */
    protected function getPath():string
    {
        return $this->getConfig('path')?:'';
    }

    /**
     * 参数拼接
     * @param array $params
     * @return array
     */
    protected function getParams(array $params)
    {
        $append = [
            'payMethon' => 'NeoPay',
            'appid' => $this->getConfig('appid'),
            'backUrl' => $this->getConfig('notify'),
            'merchant' => 'SX'
        ];

        return array_merge($params, $append);
    }

    /**
     * 请求
     * @param array $params
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    protected function request(array $params=[]):array
    {
        /** @var Request $http */
        $http = make(Request::class);
        $response = json_decode($http->post($this->getConfig('domain').$this->getConfig('prefix').$this->getPath(), $params, true), true);
        logs(json_encode($response, JSON_UNESCAPED_UNICODE));

        return $this->response($response, $params);
    }

    /**
     * 响应
     * @param $response
     * @param array $params
     * @return array
     */
    protected function response($response, array $params=[]):array
    {
        if (!isset($response['code']) &&
            $response['code'] !== '0' &&
            !isset($response['data']) &&
            !isset($response['data']['code']) &&
            $response['data']['code'] != '00') {
            $message = Arr::get($response, 'message');
            if (!$message) {
                throw new InternalException('response is null');
            }
            $messageJson = json_decode($message, true);
            if (false === $messageJson || !Arr::has($messageJson, 'head') || !Arr::has($messageJson['head'], 'respMsg')) {
                throw new InternalException($message);
            }
            throw new InternalException($messageJson['head']['respMsg']);
        }

        $body = Arr::get($response['data'], 'resultContent');

        return [
            $params,
            $response,
            $body
        ];
    }
}